package com.example.myDesignPatterns.结构型模式.代理模式Proxy.jdk动态代理;

public class explain {
    /**
     * ProxyFactory 不是代理模式中的代理类，而是代理模式中的工厂类
     * ProxyFactory 的作用是生成代理类
     * 真正的代理类是 ProxyFactory 生成的
     */
        /**
         * package com.sun.proxy;
         * import com.itheima.proxy.dynamic.jdk.SellTickets;
         * import java.lang.reflect.InvocationHandler;
         * import java.lang.reflect.Method;
         * import java.lang.reflect.Proxy;
         * import java.lang.reflect.UndeclaredThrowableException;
         *
         * public final class $Proxy0 extends Proxy implements SellTickets {
         *      private static Method m1;
         *      private static Method m2;
         *      private static Method m3;
         *      private static Method m0;
         *
         *  public $Proxy0(InvocationHandler invocationHandler) {
         *      super(invocationHandler);
         *  }
         *  static {
         *      try {
         *          m1 = Class.forName("java.lang.Object").getMethod("equals",Class.forName("java.lang.Object"));
         *          m2 =Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
         *          m3 =Class.forName("com.example.myDesignPatterns.结构型模式.代理模式.common.SellTickets").getMethod("sell", new Class[0]);
         *          m0 =Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
         *          return;
         *          }
         *          catch (NoSuchMethodException noSuchMethodException) {
         *              throw new NoSuchMethodError(noSuchMethodException.getMessage());
         *          }
         *          catch (ClassNotFoundException classNotFoundException) {
         *              throw new NoClassDefFoundError(classNotFoundException.getMessage());
         *          }
         *         }
         *
         * public final boolean equals(Object object) {
         *      try {
         *          return (Boolean)this.h.invoke(this, m1, new Object[]{object});
         *          }
         *      catch (Error | RuntimeException throwable) {
         *          throw throwable;
         *          }
         *      catch (Throwable throwable) {
         *          throw new UndeclaredThrowableException(throwable);
         *          }
         * }
         *
         * public final String toString() {
         *      try {
         *          return (String)this.h.invoke(this, m2, null);
         *          }
         *      catch (Error | RuntimeException throwable) {
         *          throw throwable;
         *          }
         *      catch (Throwable throwable) {
         *          throw new UndeclaredThrowableException(throwable);
         *          }
         * }
         *
         * public final int hashCode() {
         *      try {
         *          return (Integer)this.h.invoke(this, m0, null);
         *          }
         *      catch (Error | RuntimeException throwable) {
         *          throw throwable;
         *      }
         *      catch (Throwable throwable) {
         *          throw new UndeclaredThrowableException(throwable);
         *      }
         * }
         *
         * public final void sell() {
         *      try {
         *          this.h.invoke(this, m3, null);
         *          return;
         *          }
         *      catch (Error | RuntimeException throwable) {
         *          throw throwable;
         *      }
         *      catch (Throwable throwable) {
         *          throw new UndeclaredThrowableException(throwable);
         *      }
         * }
         *
         * }
     */
    /**
     * 从上面的类中，我们可以看到以下几个信息：
     * 代理类（$Proxy0）实现了SellTickets。这也就印证了我们之前说的真实类和代理类实
     * 现同样的接口。
     * 代理类（$Proxy0）将我们提供了的匿名内部类对象传递给了父类。
     */

    /**
     * 重点代码
     * //程序运行过程中动态生成的代理类
     * public final class $Proxy0 extends Proxy implements SellTickets {
     *      private static Method m3;
     *
     *  public $Proxy0(InvocationHandler invocationHandler) {
     *      super(invocationHandler);
     *   }
     *  static {
     *      m3 =Class.forName("com.itheima.proxy.dynamic.jdk.SellTickets").getMethod("sell", new Class[0]);
     *  }
     *  public final void sell() {
     *      this.h.invoke(this, m3, null);
     *  }
     * }
     *
     * //Java提供的动态代理相关类
     * public class Proxy implements java.io.Serializable {
     *      protected InvocationHandler h;
     *
     *      protected Proxy(InvocationHandler h) {
     *          this.h = h;
     *      }
     * }
     *
     * //代理工厂类
     * public class ProxyFactory {
     *      private TrainStation station = new TrainStation();
     *
     *  public SellTickets getProxyObject() {
     *      SellTickets sellTickets = (SellTickets)
     *      Proxy.newProxyInstance(station.getClass().getClassLoader(),
     *      station.getClass().getInterfaces(),
     *      new InvocationHandler() {
     *          public Object invoke(Object proxy, Method method,Object[] args) throws Throwable {
     *              System.out.println("代理点收取一些服务费用(JDK动态代理方式)");
     *              Object result = method.invoke(station, args);
     *              return result;
     *          }
     *      });
     *      return sellTickets;
     *     }
     * }
     *
     * //测试访问类
     * public class Client {
     *     public static void main(String[] args) {
     * //获取代理对象
     *          ProxyFactory factory = new ProxyFactory();
     *          SellTickets proxyObject = factory.getProxyObject();
     *          proxyObject.sell();
     *      }
     * }
     *
     * 执行流程如下：
     * 1. 在测试类中通过代理对象调用sell()方法
     * 2. 根据多态的特性，执行的是代理类（$Proxy0）中的sell()方法
     * 3. 代理类（$Proxy0）中的sell()方法中又调用了InvocationHandler接口的子实现类对象的invoke方法
     * 4. invoke方法通过反射执行了真实对象所属类(TrainStation)中的sell()方法
     */
}
